#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "testfunc.h"

int Callback_0()//Call back Function 1
{
    printf(" Hello ,this is CallBack_0 \n");
    return 0;
}

int Callback_1(int x)//Call back Function 1
{
    printf(" Hello ,this is CallBack_1:x = %d \n", x);
    return 0;
}

int Callback_2(int x) //Call back Function 2
{
    printf("Hello ,this is Callback_2: x = %d\n", x);
    return 0;
}

int Callback_3(int x) //Call back Function 3
{
    printf("Hello ,this is Callback_3:x = %d \n", x);
    return 0;
}

int Handle_0(int (*Callback)())
{
    printf("Entering Handle Function. \n");
    Callback();
    printf("Leaving  Handle Function. \n");
    
}

int Handle(int y,int (*Callback)(int))
{
    printf("Entering Handle Function. \n");
    Callback(y);
    printf("Leaving  Handle Function. \n");
    
}

void handle_callback()
{
        //回调函数 便于解耦，丝毫不修改库函数 实现
    
    printf("Entering  Main Function. \n\n");
   //传函数名就是传函数指针，回调函数其实就是函数指针的一种用法
   // A "call back "is any function that is called by another function 
   //which takes the first funtion as a parameter.
    //Handle_0(Callback_0); 
    int a = 2;
    int b = 4;
    int c = 6;
    Handle(a, Callback_0);
    Handle(a, Callback_1);
    Handle(b, Callback_2);
    Handle(c, Callback_3);
    printf("\nLeaving Main Function. \n");
}
// test practise
typedef void(*listen)(int);
listen mlisten[3];

void register_observer(listen obs)
{
    for(int i = 0;i<3;i++)
    {
        if(mlisten[i] == 0)
        {
            mlisten[i] == obs;
            return;
        }
    }
}
void listen0(int i)
{
    printf("listen0 received i =%d \n",i);
}
void listen1(int i)
{
    printf("listen1 received i =%d \n",i);
}
void listen2(int i)
{
    printf("listen2 received i =%d \n",i);
}

void notify_all_observer(int val)
{
    for(int i = 0;i < sizeof(mlisten)/sizeof(mlisten[0]);i++)
    {
        if (mlisten[i] != 0)
        {
            mlisten[i](val);
        }
    }
}

void practise_handle_callback()
{
    int i = 0;
    printf("lis1:%d\n",listen0);
    register_observer(listen0);
    printf("lis2:%d\n",listen1);
    register_observer(listen1);
    register_observer(listen2);
    while (1)
    {
        scanf("%d\n",&i);
        printf("%d\n",i);
        notify_all_observer(i);
    }
    
}
int main()
{
    handle_callback();
    practise_handle_callback();
    return 0;

}